package events;

import java.util.HashMap;
import java.util.List;

import eduni.simjava.Sim_entity;
import eduni.simjava.Sim_event;
import eduni.simjava.Sim_port;
import eduni.simjava.Sim_stat;
import eduni.simjava.Sim_system;

public class LAN extends Sim_entity{
	
	private Sim_port in;
	private HashMap<Client, Sim_port> clientsPorts;

	private double bandwidth;
	
	private Sim_stat stat;
	private static List<Client> clients;
	
	public LAN(String name, double bandwith){
		super(name);
		
		this.bandwidth = bandwith;
		in = new Sim_port("in");
		add_port(in);
		
		stat = new Sim_stat();
        stat.add_measure(Sim_stat.THROUGHPUT);
        stat.add_measure(Sim_stat.ARRIVAL_RATE);
        stat.add_measure(Sim_stat.QUEUE_LENGTH);
        stat.add_measure(Sim_stat.SERVICE_TIME);
        stat.add_measure(Sim_stat.UTILISATION);
        stat.add_measure(Sim_stat.WAITING_TIME);
        
        set_stat(stat);
        
        clientsPorts = new HashMap<Client, Sim_port>();
	}
	
	public void body() {

		long i = 0;
		
		while (Sim_system.running()) {

			Sim_event e = new Sim_event();
			// Get the next event
			sim_get_next(e);

			if (e.get_tag() == EventType.REQUEST_FILE) {

				Client client = (Client) e.get_data();
				long fileSize = client.getAmountToDownload();
				double uploadTime = fileSize / this.bandwidth;
				
				// Process the event
				sim_process(uploadTime);

				// The event has completed service
				sim_completed(e);
				i++;
				if(i % 1000 == 0){
					System.out.println("ENDED: "+i);
				}
				
				//Sending transfer confirmation for client
				sim_schedule(clientsPorts.get(client), 0.0, EventType.LAN_CONFIRMATION, 0);
			}
		}
	}

	public void createConnectionForClients(List<Client> clients) {
		for (Client client : clients){
			Sim_port port = new Sim_port("outTo"+client.get_name());
			add_port(port);
			
			clientsPorts.put(client, port);
		}
	}
	
	public HashMap<Client, Sim_port> getPorts(){
		return clientsPorts;
	}

	public static void setClients(List<Client> clients) {
		LAN.clients = clients;
	}
}
